package com.wl.service.impl;

import com.aliyuncs.utils.StringUtils;
import com.wl.constant.Constant;
import com.wl.mapper.CommentsMapper;
import com.wl.mapper.UsersMapper;
import com.wl.pojo.Comments;
import com.wl.pojo.model.CommentManagement;
import com.wl.pojo.model.CommentModel;
import com.wl.pojo.model.UserToken;
import com.wl.service.CommentsService;
import com.wl.util.MyUtil;
import com.wl.util.MybatisUtils;
import com.wl.util.RedisUtil;
import com.wl.util.TokenUtils;
import redis.clients.jedis.Jedis;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @program: treeHole
 * @author: 吴磊
 * @create: 2021-07-06 18:16
 */
public class CommentsServiceImpl implements CommentsService {

    private CommentsMapper commentsMapper = MybatisUtils.getMapper(CommentsMapper.class);
    private UsersMapper usersMapper = MybatisUtils.getMapper(UsersMapper.class);

    @Override
    public Map<String, Object> getAllComments(HttpServletRequest request) {
        Map<String, Object> resmap = new HashMap<>();
        String page = request.getParameter("curPage");
        int curPage = 1;
        if (page != null && Integer.parseInt(page) > 0) {
            curPage = Integer.parseInt(page);
        }
        int start = (curPage - 1) * 10;
        int total = commentsMapper.getAllCommentsCount();
        List<CommentManagement> allCommentList = commentsMapper.getAllComments(start);
        resmap.put("total", total);
        resmap.put("comments", allCommentList);
        return resmap;
    }

    @Override
    public Map<String, Object> insertComment(HttpServletRequest request, Comments comments) {
        Jedis jedis = RedisUtil.getJedis();
        if ((jedis.zrank(Constant.INTEGRAL, comments.getArticleId()) + "").equals("null")) {
            jedis.close();
            return null;
        }
        UserToken user = TokenUtils.getUser(request);
        String userId = user.getUserId();
        String commentId = MyUtil.getUUID();
        String currentDetailedTime = MyUtil.getCurrentDetailedTime();
        comments.setUserId(userId);
        comments.setCommentDate(currentDetailedTime);
        comments.setCommentId(commentId);
        if (StringUtils.isEmpty(comments.getParentCommentId())) {
            comments.setParentCommentId("");
        }
        Integer i = commentsMapper.insert(comments);
        HashMap<String, Object> map = new HashMap<>();

        jedis.incr(comments.getArticleId() + "_commentCount");
        map.put("commentCount", jedis.get(comments.getArticleId() + "_commentCount"));
        map.put("isInsertOk", i <= 0 ? false : true);
        RedisUtil.setIntegralByComments(Constant.INTEGRAL, comments.getArticleId(), jedis);
        jedis.close();
        return map;
    }

    @Override
    public Map<String, Object> getCommentByArticleId(HttpServletRequest request, String articleId) {
        //获得所有的一级评论
        List<CommentModel> levelOneComment = commentsMapper.getCommentsByArticleIdAndParentCommentIdIsNull(articleId);
        levelOneComment = getCommentModels(levelOneComment);
        List<CommentModel> sons = getSons(levelOneComment);
        HashMap<String, Object> map = new HashMap<>();
        map.put("CommentModels", sons);
        return map;
    }

    @Override
    public Map<String, Object> deleteCommentsByCommentId(HttpServletRequest request, String commentId) {
        Comments comments = commentsMapper.getCommentsByCommentId(commentId);
        Map<String, Object> map = new HashMap<>();
        if (comments == null) {
            map.put("count", -1);
            return map;
        }
        List<String> commentIdList = new ArrayList();
        commentIdList.add(commentId);
        List<CommentModel> sons = getSons(commentId);
        getChildComments(sons, commentIdList);
        //以上获取了所有评论的Id
        //1、根据评论ID获取文章Id
        String articleId = commentsMapper.getArticleIdByCommentId(commentId);
        //更新文章评论数
        Jedis jedis = RedisUtil.getJedis();
        String nowCommentCount = jedis.get(articleId + "_commentCount");
        jedis.decrBy(articleId + "_commentCount", commentIdList.size());
        //返回最新评论数
        String leastCommentCount = jedis.get(articleId + "_commentCount");
        int deleterCount = Integer.parseInt(nowCommentCount) - Integer.parseInt(leastCommentCount);
        RedisUtil.setIntegralByDeleteComments(Constant.INTEGRAL, articleId, deleterCount, jedis);
        jedis.close();
        //删除以上查出的所有评论
        commentsMapper.deleteCommentsByIdList(commentIdList);
        map.put("commentCount", leastCommentCount);
        return map;
    }

    @Override
    public Map<String, Object> commentUp(HttpServletRequest request, String commentId) {
        HashMap<String, Object> map = new HashMap<>();
        UserToken loginUser = TokenUtils.getUser(request);
        String userId = loginUser.getUserId();
        Jedis jedis = RedisUtil.getJedis();
        String commentUp = commentId + "_up";
        if (jedis.sismember(commentUp, userId)) {
            jedis.srem(commentUp, userId);
        } else {
            jedis.sadd(commentUp, userId);
        }
        Long commentUpCount = jedis.scard(commentUp);
        jedis.close();
        map.put("commentUpCount", commentUpCount);
        return map;
    }

    @Override
    public Map<String, Object> getCommentManagementByUserId(HttpServletRequest request) {
        Integer curPage = Integer.valueOf(request.getParameter("curPage"));
        Map<String, Object> map = new HashMap<>();
        UserToken userToken = TokenUtils.getUser(request);
        String userId = userToken.getUserId();
        //查询总评论数，用来分页查询
        Integer count = commentsMapper.getCountByUserId(userId);
        map.put("total", count);
        int totalPage = (count + 20 - 1) / 20;
        if (totalPage == 0) {
            map.put("total", 0);
            map.put("totalPage", 0);
            map.put("collect", new ArrayList<>());
            return map;
        }
        if (curPage < 1) {
            curPage = 1;
        }
        if (curPage > totalPage) {
            curPage = totalPage;
        }
        map.put("totalPage", totalPage);
        long longTime = System.currentTimeMillis();
        List<CommentManagement> comments = commentsMapper.getCommentManagementByUserId(userId, (curPage - 1) * 20);
        List<CommentManagement> collect = comments.stream().map(comment -> {
            String commentDate = comment.getCommentDate();
            long commentTime = MyUtil.parseTimeToString(commentDate);
            long time = longTime - commentTime;
            String overdueTime = "";
            long howTime = time / 1000 / 60;
            if (howTime < 60) {
                if (howTime <= 2) {
                    overdueTime = "刚刚";
                } else {
                    overdueTime = howTime + "分钟前";
                }
            } else if (howTime < 1440) {
                overdueTime = howTime / 60 + "小时前";
            } else if (howTime < 43200) {
                overdueTime = howTime / 1440 + "天前";
            } else if (howTime < 15768000) {
                overdueTime = howTime / 43200 + "月前";
            } else {
                overdueTime = howTime / 15768000 + "年前";
            }
            comment.setOverdueTime(overdueTime);
            return comment;
        }).collect(Collectors.toList());
        map.put("collect", collect);
        return map;
    }

    @Override
    public Map<String, Object> getOwnerComments(HttpServletRequest request) {
        Map<String, Object> map = new HashMap<>();
        Integer curPage = Integer.valueOf(request.getParameter("curPage"));
        UserToken userToken = TokenUtils.getUser(request);
        String userId = userToken.getUserId();
        //查询总评论数，用来分页查询
        Integer count = commentsMapper.getOwnerCommentCount(userId);
        map.put("total", count);
        int totalPage = (count + 20 - 1) / 20;
        if (totalPage == 0) {
            map.put("total", 0);
            map.put("totalPage", 0);
            map.put("collect", new ArrayList<>());
            return map;
        }
        if (curPage < 1) {
            curPage = 1;
        }
        if (curPage > totalPage) {
            curPage = totalPage;
        }
        map.put("totalPage", totalPage);
        long longTime = System.currentTimeMillis();
        List<CommentManagement> comments = commentsMapper.getOwnerComment(userId, (curPage - 1) * totalPage);
        List<CommentManagement> collect = comments.stream().map(comment -> {
            String commentDate = comment.getCommentDate();
            long commentTime = MyUtil.parseTimeToString(commentDate);
            long time = longTime - commentTime;
            String overdueTime = "";
            long howTime = time / 1000 / 60;
            if (howTime < 60) {
                if (howTime <= 2) {
                    overdueTime = "刚刚";
                } else {
                    overdueTime = howTime + "分钟前";
                }
            } else if (howTime < 1440) {
                overdueTime = howTime / 60 + "小时前";
            } else if (howTime < 43200) {
                overdueTime = howTime / 1440 + "天前";
            } else if (howTime < 15768000) {
                overdueTime = howTime / 43200 + "月前";
            } else {
                overdueTime = howTime / 15768000 + "年前";
            }
            comment.setOverdueTime(overdueTime);
            return comment;
        }).collect(Collectors.toList());
        map.put("collect", collect);
        return map;
    }

    private void getChildComments(List<CommentModel> children, List<String> commentIdList) {
        if (children == null || children.size() <= 0) {
            return;
        }
        for (CommentModel child : children) {
            String commentId = child.getCommentId();
            commentIdList.add(commentId);
            List<CommentModel> sons = getSons(commentId);
            getChildComments(sons, commentIdList);
        }
    }

    /**
     * 递归查询子评论
     *
     * @param parents
     * @return
     */
    private List<CommentModel> getSons(List<CommentModel> parents) {
        if (parents == null || parents.size() <= 0) {
            return new ArrayList<>();
        }
        for (CommentModel parent : parents) {
            Jedis jedis = RedisUtil.getJedis();
            Long upCount = jedis.scard(parent.getCommentId() + "_up");
            parent.setUpCount(upCount + "");
            jedis.close();
            UserToken userInfo = usersMapper.getUserTokenById(parent.getUserId());
            parent.setUserToken(userInfo);
            String parentCommentId = parent.getCommentId();
            List<CommentModel> sons = getSons(parentCommentId);
            sons = getCommentModels(sons);
            parent.setChildComment(getSons(sons));
        }
        return parents;
    }

    private List<CommentModel> getCommentModels(List<CommentModel> commentModel) {
        commentModel = commentModel.stream().map(comment -> {
            long longTime = System.currentTimeMillis();
            String commentDate = comment.getCommentDate();
            long commentTime = MyUtil.parseTimeToString(commentDate);
            long time = longTime - commentTime;
            String overdueTime = "";
            long howTime = time / 1000 / 60;
            if (howTime < 60) {
                if (howTime <= 2) {
                    overdueTime = "刚刚";
                } else {
                    overdueTime = howTime + "分钟前";
                }
            } else if (howTime < 1440) {
                overdueTime = howTime / 60 + "小时前";
            } else if (howTime < 43200) {
                overdueTime = howTime / 1440 + "天前";
            } else if (howTime < 15768000) {
                overdueTime = howTime / 43200 + "月前";
            } else {
                overdueTime = howTime / 15768000 + "年前";
            }
            comment.setOverdueTime(overdueTime);
            return comment;
        }).collect(Collectors.toList());
        return commentModel;
    }

    /**
     * 通过父评论Id获取子评论
     *
     * @param parentCommentsId
     * @return
     */
    private List<CommentModel> getSons(String parentCommentsId) {
        return commentsMapper.getCommentByParentId(parentCommentsId);
    }
}
